/**
 * 
 */
package org.arpit.masteringextjs.dao.impl;

import java.util.List;

import org.arpit.masteringextjs.dao.DBUtility;
import org.arpit.masteringextjs.dao.UserDAO;
import org.arpit.masteringextjs.domain.User;
import org.hibernate.Criteria;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.criterion.Restrictions;

/**
 * @author Arpit.Rathore
 *
 */
public class UserDAOImpl implements UserDAO {

	private static UserDAO userDAO;
	private SessionFactory sessionFactory = DBUtility.getSessionFactory();
	private UserDAOImpl () {
		
	}
	
	@Override
	public User create(User user) {
		Session session = sessionFactory.openSession();
		session.beginTransaction();
		User createdUser = (User) session.merge(user);
		session.getTransaction().commit();
		session.close();
		return createdUser;
	}
	
	@Override
	public User update(User user) {
		if(user.getId() == null || user.getId() == 0) {
			throw new IllegalArgumentException("Invalid data");
		}
		Session session = sessionFactory.openSession();
		session.beginTransaction();
		User createdUser = (User) session.merge(user);
		session.getTransaction().commit();
		session.close();
		return createdUser;
	}

	@Override
	public User findByUsername(String userName) {
		Session session = sessionFactory.openSession();
		session.beginTransaction();
		Criteria crit = session.createCriteria(User.class);
		crit.add(Restrictions.eq("userName", userName));
		List<User> users = crit.list();
		if(users.isEmpty()) {
			return null;
		}
		User user = users.get(0);
		session.getTransaction().commit();
		session.close();
		return user;
	}
	
	public static UserDAO getInstance() {
		if(userDAO == null) {
			userDAO = new UserDAOImpl();
		}
		return userDAO;
	}

	@Override
	public User findById(Long id) {
		Session session = sessionFactory.openSession();
		session.beginTransaction();
		Criteria crit = session.createCriteria(User.class);
		crit.add(Restrictions.eq("id", id));
		List<User> users = crit.list();
		if(users.isEmpty()) {
			return null;
		}
		User user = users.get(0);
		session.getTransaction().commit();
		session.close();
		return user;
	}

	@Override
	public List<User> findAll() {
		Session session = sessionFactory.openSession();
		session.beginTransaction();
		Criteria crit = session.createCriteria(User.class);
		crit.setResultTransformer(Criteria.DISTINCT_ROOT_ENTITY);
		List<User> users = crit.list();
		session.getTransaction().commit();
		session.close();
		return users;
	}

	@Override
	public void delete(Long id) {
		Session session = sessionFactory.openSession();
		session.beginTransaction();
		Criteria crit = session.createCriteria(User.class);
		crit.add(Restrictions.eq("id", id));
		List<User> users = crit.list();
		if(users.isEmpty()) {
			throw new IllegalArgumentException("User with id " + id +" not found");
		}
		User user = users.get(0);
		session.delete(user);
		session.getTransaction().commit();
		session.close();
	}

}
